using B.S.XZYData.Api.Wrter.Application.Command.Plan;
using B.S.XZYData.Domain.LJC;
using B.S.XZYData.ErrorCode;
using B.S.XZYData.Infrastructure.Interface;
using MediatR;
using Microsoft.Extensions.Logging;
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using System.Linq;
using System.Transactions;

namespace B.S.XZYData.Api.Wrter.Application.Handler.Plan
{
    /// <summary>
    /// 导入生产计划处理器
    /// </summary>
    public class ImportPlanHandler : IRequestHandler<ImportPlanCommand, ApiResult<ImportPlanResult>>
    {
        private readonly IBaseRepository<PlanModel> _planRepository;
        private readonly IBaseRepository<PlanItemModel> _planItemRepository;
        private readonly IBaseRepository<ProductModel> _productRepository;
        private readonly ILogger<ImportPlanHandler> _logger;

        public ImportPlanHandler(
            IBaseRepository<PlanModel> planRepository,
            IBaseRepository<PlanItemModel> planItemRepository,
            IBaseRepository<ProductModel> productRepository,
            ILogger<ImportPlanHandler> logger)
        {
            _planRepository = planRepository;
            _planItemRepository = planItemRepository;
            _productRepository = productRepository;
            _logger = logger;
        }

        public async Task<ApiResult<ImportPlanResult>> Handle(ImportPlanCommand request, CancellationToken cancellationToken)
        {
            try
            {
                var result = new ImportPlanResult();
                var errorMessages = new List<string>();

                using var stream = new MemoryStream(request.FileBytes);
                
                // 根据文件扩展名决定使用哪种工作簿
                IWorkbook workbook;
                try
                {
                    // 尝试作为 XLSX 文件打开
                    workbook = new XSSFWorkbook(stream);
                }
                catch
                {
                    // 如果失败，重置流并尝试作为 XLS 文件打开
                    stream.Position = 0;
                    workbook = new HSSFWorkbook(stream);
                }

                if (workbook.NumberOfSheets == 0)
                {
                    return new ApiResult<ImportPlanResult>
                    {
                        Code = ApiEnum.Fail,
                        Msg = "Excel文件中没有工作表"
                    };
                }

                var worksheet = workbook.GetSheetAt(0);
                
                // 检查是否有数据行（第一行是标题）
                if (worksheet.LastRowNum < 1)
                {
                    return new ApiResult<ImportPlanResult>
                    {
                        Code = ApiEnum.Fail,
                        Msg = "Excel文件中没有数据"
                    };
                }

                var plans = new Dictionary<string, PlanModel>();
                var planItems = new List<PlanItemModel>();

                // 从第二行开始读取数据（跳过标题行）
                for (int rowIndex = 1; rowIndex <= worksheet.LastRowNum; rowIndex++)
                {
                    var row = worksheet.GetRow(rowIndex);
                    if (row == null) continue;

                    try
                    {
                        // 读取计划单号
                        var planCode = GetCellValue(row, 0);
                        if (string.IsNullOrWhiteSpace(planCode))
                        {
                            errorMessages.Add($"第{rowIndex + 1}行：计划单号不能为空");
                            continue;
                        }

                        // 检查或创建计划
                        if (!plans.ContainsKey(planCode))
                        {
                            var existingPlan = _planRepository.GetAll()
                                .Where(x => x.Code == planCode).ToList().FirstOrDefault();
                            
                            if (existingPlan != null)
                            {
                                plans[planCode] = existingPlan;
                            }
                            else
                            {
                                var newPlan = new PlanModel
                                {
                                    Code = planCode,
                                    Remark = GetCellValue(row, 1),
                                    CreateTime = DateTime.Now,
                                    CreateBy = request.OperateBy
                                };
                                plans[planCode] = newPlan;
                            }
                        }

                        // 读取产品信息
                        var productCode = GetCellValue(row, 3);
                        if (!string.IsNullOrWhiteSpace(productCode))
                        {
                            var product = _productRepository.GetAll()
                                .Where(x => x.Code == productCode).ToList().FirstOrDefault();
                            
                            if (product == null)
                            {
                                errorMessages.Add($"第{rowIndex + 1}行：产品编号 {productCode} 不存在");
                                continue;
                            }

                            var quantityStr = GetCellValue(row, 7);
                            if (!int.TryParse(quantityStr, out int quantity))
                            {
                                errorMessages.Add($"第{rowIndex + 1}行：计划数量格式不正确");
                                continue;
                            }

                            var planItem = new PlanItemModel
                            {
                                PlanId = plans[planCode].Id,
                                ProductCode = productCode,
                                ProductName = GetCellValue(row, 4),
                                Spec = GetCellValue(row, 5),
                                Quantity = quantity,
                                DoneQuantity = 0
                            };
                            planItems.Add(planItem);
                        }
                    }
                    catch (Exception ex)
                    {
                        errorMessages.Add($"第{rowIndex + 1}行：处理数据时发生错误 - {ex.Message}");
                    }
                }

                if (errorMessages.Any())
                {
                    result.ErrorMessages = errorMessages.ToArray();
                    result.FailCount = errorMessages.Count;
                    return new ApiResult<ImportPlanResult>
                    {
                        Code = ApiEnum.Fail,
                        Msg = "导入过程中发现错误",
                        Data = result
                    };
                }

                // 保存数据
                using var transaction = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled);
                
                // 保存新计划
                var newPlans = plans.Values.Where(x => x.Id == 0).ToList();
                if (newPlans.Any())
                {
                    foreach (var plan in newPlans)
                    {
                        await _planRepository.CreateAsync(plan);
                    }
                    result.SuccessCount += newPlans.Count;
                }

                // 更新计划ID并保存计划项
                foreach (var item in planItems)
                {
                    var plan = plans.Values.First(x => x.Code == GetPlanCodeByItem(item));
                    item.PlanId = plan.Id;
                }

                if (planItems.Any())
                {
                    foreach (var item in planItems)
                    {
                        await _planItemRepository.CreateAsync(item);
                    }
                    result.SuccessCount += planItems.Count;
                }

                transaction.Complete();

                result.TotalCount = worksheet.LastRowNum;

                _logger.LogInformation($"成功导入生产计划数据 {result.SuccessCount} 条，操作人：{request.OperateBy}");

                return new ApiResult<ImportPlanResult>
                {
                    Code = ApiEnum.Success,
                    Msg = $"成功导入 {result.SuccessCount} 条数据",
                    Data = result
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"导入生产计划失败，操作人：{request.OperateBy}");
                return new ApiResult<ImportPlanResult>
                {
                    Code = ApiEnum.Fail,
                    Msg = $"导入失败：{ex.Message}"
                };
            }
        }

        private string GetCellValue(IRow row, int columnIndex)
        {
            var cell = row.GetCell(columnIndex);
            if (cell == null) return string.Empty;

            return cell.CellType switch
            {
                CellType.String => cell.StringCellValue,
                CellType.Numeric => cell.NumericCellValue.ToString(),
                CellType.Boolean => cell.BooleanCellValue.ToString(),
                CellType.Formula => cell.CellFormula,
                _ => string.Empty
            };
        }

        private string GetPlanCodeByItem(PlanItemModel item)
        {
            // 这里需要根据实际业务逻辑实现
            // 暂时返回空字符串，您需要根据实际情况调整
            return string.Empty;
        }
    }
} 